home *** CD-ROM | disk | FTP | other *** search
- /*
- Load and convert a WAV file, play it with 'ahi.device'
-
- Written by Oliver Gantert
-
- 31.04.2000 - Yeah, this works!
- */
-
- #include "orbit.h"
- #include <devices/ahi.h>
- #include <clib/ahi_protos.h>
- #include <stdio.h>
-
- struct RIFF_Header
- {
- ULONG ChunkID; /* must be 0x52494646 */
- ULONG ChunkSize; /* little endian! */
- ULONG Format; /* must be 0x57415645 */
- ULONG Subchunk1ID; /* must be 0x666d7420 */
- ULONG Subchunk1Size; /* little endian, must be 16 */
- UWORD AudioFormat; /* little endian, must be 1 */
- UWORD NumChannels; /* little endian, Mono = 1, Stereo = 2 */
- ULONG SampleRate; /* little endian, 44100 etc. */
- ULONG ByteRate; /* little endian, == SampleRate * NumChannels * BitsPerSample/8 */
- UWORD BlockAlign; /* little endian, == NumChannels * BitsPerSample/8 */
- UWORD BitsPerSample; /* little endian, 8, 16, etc. */
- ULONG Subchunk2ID; /* must be 0x64617461 */
- ULONG Subchunk2Size; /* little endian, == NumSamples * NumChannels * BitsPerSample/8 */
- };
-
- struct ASample
- {
- ULONG SampleRate;
- ULONG Size;
- UBYTE *SampleData;
- ULONG Type;
- };
-
- struct MsgPort *AHImp = NULL;
- struct AHIRequest *AHIio = NULL;
- struct ASample *smp[3] = {NULL, NULL, NULL};
- ULONG ahi_available = 0,
- ahi_open = 0;
-
- UWORD ChangeEndianW(UWORD wert)
- {
- UBYTE t;
- union
- {
- UBYTE c[2];
- UWORD w;
- } u;
-
- u.w = wert;
- t = u.c[0];
- u.c[0] = u.c[1];
- u.c[1] = t;
-
- return(u.w);
- }
-
- ULONG ChangeEndianL(ULONG wert)
- {
- UBYTE t;
- union
- {
- UBYTE c[4];
- ULONG w;
- } u;
-
- u.w = wert;
- t = u.c[0];
- u.c[0] = u.c[3];
- u.c[3] = t;
- t = u.c[1];
- u.c[1] = u.c[2];
- u.c[2] = t;
-
- return(u.w);
- }
-
- struct ASample *LoadWAVSample(STRPTR filename)
- {
- struct ASample *smp = NULL;
- struct RIFF_Header *riff;
- FILE *file;
- UWORD *smpdata;
- ULONG i;
-
- if (file = fopen(filename, "rb"))
- {
- if (riff = (struct RIFF_Header *)malloc(sizeof(struct RIFF_Header)))
- {
- fread(riff, sizeof(struct RIFF_Header), 1, file);
- /*
- Check if it's a standard RIFF WAVE file.
- */
- if ((riff->ChunkID == 0x52494646) && (riff->Format == 0x57415645) &&
- (riff->Subchunk1ID == 0x666d7420) && (riff->Subchunk2ID == 0x64617461))
- {
- riff->Subchunk1Size = ChangeEndianL(riff->Subchunk1Size);
- riff->AudioFormat = ChangeEndianW(riff->AudioFormat);
- riff->NumChannels = ChangeEndianW(riff->NumChannels);
- riff->SampleRate = ChangeEndianL(riff->SampleRate);
- riff->BitsPerSample = ChangeEndianW(riff->BitsPerSample);
- riff->Subchunk2Size = ChangeEndianL(riff->Subchunk2Size);
- /*
- More checks.
- */
- if ((riff->Subchunk1Size == 16) && (riff->AudioFormat == 1))
- {
- if (smp = (struct ASample *)malloc(sizeof(struct ASample)))
- {
- smp->SampleRate = riff->SampleRate;
- smp->Size = riff->Subchunk2Size;
- if (riff->NumChannels == 1)
- {
- if (riff->BitsPerSample == 8)
- smp->Type = AHIST_M8S;
- else
- smp->Type = AHIST_M16S;
- }
- else
- {
- if (riff->BitsPerSample == 8)
- smp->Type = AHIST_S8S;
- else
- smp->Type = AHIST_S16S;
- }
- if (smp->SampleData = (UBYTE *)malloc(smp->Size))
- {
- fread(smp->SampleData, smp->Size, 1, file);
- /*
- Change endian of 16bit data
- */
- if (riff->BitsPerSample > 8)
- {
- smpdata = (UWORD *)smp->SampleData;
- for (i = 0; i < (smp->Size>>1); i++)
- {
- smpdata[i] = ChangeEndianW(smpdata[i]);
- }
- }
- }
- else
- {
- free(smp);
- smp = NULL;
- }
- }
- }
- }
- free(riff);
- }
- fclose(file);
- }
- return(smp);
- }
-
- VOID FreeASample(struct ASample *smp)
- {
- if (smp)
- {
- if (smp->SampleData)
- free(smp->SampleData);
- free(smp);
- }
- }
-
- /*
- ==============
- THE ORBIT PART
- ==============
- */
-
- int InitSound()
- {
- if (AHImp = (struct MsgPort *)CreateMsgPort())
- {
- if (AHIio = (struct AHIRequest *)CreateIORequest(AHImp, sizeof(struct AHIRequest)))
- {
- AHIio->ahir_Version = 4;
- if (!OpenDevice(AHINAME, 0, (struct IORequest *)AHIio, 0))
- {
- ahi_open = 1;
- if (smp[0] = LoadWAVSample("sounds/phaser.wav"))
- {
- if (smp[1] = LoadWAVSample("sounds/explosion1.wav"))
- {
- if (smp[2] = LoadWAVSample("sounds/communicator.wav"))
- {
- AHIio->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
- AHIio->ahir_Std.io_Command = CMD_WRITE;
- AHIio->ahir_Std.io_Offset = 0;
- AHIio->ahir_Volume = 0x10000;
- AHIio->ahir_Position = 0x8000;
- AHIio->ahir_Link = NULL;
- ahi_available = 1;
- return(1);
- }
- FreeASample(smp[1]);
- }
- FreeASample(smp[0]);
- }
- CloseDevice((struct IORequest *)AHIio);
- }
- DeleteIORequest((struct IORequest *)AHIio);
- }
- DeleteMsgPort(AHImp);
- }
- return(0);
- }
-
- int PlayAudio(enum sounds nSound)
- {
- if (ahi_available)
- {
- AHIio->ahir_Std.io_Data = smp[nSound]->SampleData;
- AHIio->ahir_Std.io_Length = smp[nSound]->Size;
- AHIio->ahir_Frequency = smp[nSound]->SampleRate;
- AHIio->ahir_Type = smp[nSound]->Type;
- SendIO((struct IORequest *)AHIio);
- WaitIO((struct IORequest *)AHIio);
- return(1);
- }
- return(0);
- }
-
- void FinishSound()
- {
- ahi_available = 0;
- if (AHIio)
- {
- if (ahi_open)
- {
- CloseDevice((struct IORequest *)AHIio);
- ahi_open = 0;
- }
- DeleteIORequest((struct IORequest *)AHIio);
- AHIio = NULL;
- }
- if (AHImp)
- {
- DeleteMsgPort(AHImp);
- AHImp = NULL;
- }
- if (smp[0])
- FreeASample(smp[0]);
- if (smp[1])
- FreeASample(smp[1]);
- if (smp[2])
- FreeASample(smp[2]);
- }
-